#ifndef GAME_OBJECT_H
#define GAME_OBJECT_H

class GameObject;
class APanzer;
class AIPanzer;
class PPanzer;
class Bullet;
class Bonus;
class Staff;
class Wall;

//USEFUL FUNCTIONS FOR ANGLES
float COS (float angle);
float SIN (float angle);
float ROT_RIGHT (float angle);
float ROT_LEFT (float angle);
float ROT_BACK (float angle);
//---------------------------

#include "manager.h"
#include "RenderSystem.h"
#include "Timers.h"

class GameObject : public RenderObject
{
protected:
	Timers &Timer();
	void Explode();

public:
	GameObject();
	GameObject(unsigned int id, unsigned int gid, Pool* p, float x, float y);
	virtual ~GameObject();

	int iHP;
	Pool *pParent;
	unsigned int uiID;
	unsigned int uiGroupID;							//is it panzer, or bullet, or smth else. You can look in defines.h
	virtual void Message (Msg *message)=0;			//used by pool to send a message for object
};

class APanzer : public GameObject
{
protected:
	//moving
	bool TimerMove_IsMove;
	bool TimerMove_IsStopped;
	unsigned int TimerMove_LeftTime;
	Point2D Destination;
	Point2D Depature;
	float Speed;

	//shooting
	bool TimerShoot_IsReloading;
	unsigned int TimerShoot_ReloadingTime;			//reloading the gun takes uiShootCD micro sec
	unsigned int TimerShoot_LeftTime;
public:
	APanzer();
	APanzer(unsigned int id, unsigned int gid, Pool* p, float x, float y, float dir, unsigned int type);
	virtual ~APanzer();

	unsigned int uiType;
	void Shoot();					// FIRE!!! =)
	virtual void Message (Msg *message)=0;
};

class PPanzer : public APanzer
{
public:
	PPanzer(unsigned int id, unsigned int gid, Pool* p, float x, float y, float dir, unsigned int type);
	virtual ~PPanzer();

	void Message (Msg *message);

private:
	void Upgrade();
	unsigned int IdTmerBonus;
};

class AIPanzer : public APanzer
{
public:
	AIPanzer();
	AIPanzer(unsigned int id, unsigned int gid, Pool* p, float x, float y, float dir, unsigned int type);
	virtual ~AIPanzer();

	bool Colored;
	void Message (Msg *message);

private:
	bool TimerThinking_IsThinking;
	unsigned int TimerThinking_LeftTime;
	unsigned int TimerThinking_ThinkingTime;

	void TryToMove(int shoot, int forw, int right, int left, int back); // chances
};

class Bullet : public GameObject
{
protected:
	unsigned int TimerMove_LeftTime;
	float Speed;
public:
	Bullet(unsigned int id, unsigned int gid, Pool* p, float x, float y, float dir, unsigned int panzerid);
	~Bullet();

	unsigned int uiPanzerID;
	void Message (Msg *message);
};

class Wall : public GameObject
{
public:
	Wall(unsigned int id, unsigned int gid, Pool* p, float x, float y, bool con); //con - concrete (1) or brick (0)
	virtual ~Wall();

	bool Concrete; // 0 - brick, 1 - concrete
	void Message (Msg *message);
};

class Bonus : public GameObject
{
public:
	Bonus();
	Bonus(unsigned int id, unsigned int gid, Pool* p, float x, float y);
	virtual ~Bonus();

	void Message (Msg *message);
};

class Staff : public GameObject
{
public:
	Staff();
	Staff(unsigned int id, unsigned int gid, Pool* p, float x, float y);
	virtual ~Staff();

	void Message (Msg *message);
};

#endif